<?php

namespace Common\Logic;

use Org\Word\VicWord;

class SearchLogic
{
    const SEARCH_RECORD = "search_record";

    const GOODS_TABLE = "goods";

    const GOODS_CATE_TABLE = "goods_category";

    const SHOP_TABLE = "shop";
    
    const CACHE_KEY = "search_cache_key";

    const ORDER_BY_AVA = [
        "price" => "shop_price",
        "sale_num" => "sales_sum"
    ];

    /**
     * 搜索商品
     * @param $keyword String 必填
     * @param $user_id int 可选默认0
     * @param $p int 可选默认1
     * @param $shop_id int 可选默认全部
     * @param $cate_id int 分类 可选 默认全部
     * @param $order_by string 可选 默认综合
     * @param $order_way string 可选 默认递增
     * @param $options string 可选 默认递增
     * @return mix
     */ 
    public static function goods($param,$user_id = 0)
    {
        if( !isset($param['keyword']) || empty($param['keyword']) )
        {
            throw new \Exception("Invalid param keyword",-1);
        }
 

        $keywords = self::swcs($param['keyword']);

        // var_dump($keywords);exit;

        $param['type'] = 1;
        $param['extra_id'] = 0;

        $keywordStr = implode("|",$keywords);

        // $query = "goods_name like '%{$param['keyword']}%' OR goods_sn like '%{$param['keyword']}%'";
        $query = "goods_name REGEXP '{$keywordStr}' OR keywords REGEXP '{$keywordStr}' OR goods_remark REGEXP '{$keywordStr}'";
        // var_dump($query);die;
        $cates = self::getCates($keywordStr);

        if( $cates && count($cates) > 0 )
        {
            $query .= " OR cat_id IN(".implode(",",$cates).")";
        }

        if( isset($param['shop_id']) && !empty($param['shop_id']) )
        {
            $param['shop_id'] = intval($param['shop_id']);
            if($param['shop_id']>0)
            {
                $query .= " AND shop_id={$param['shop_id']}";
                $param['type'] = 3;
                $param['extra_id'] = $param['shop_id'];
            }
        }

        if( isset( $param['cate_id'] ) && !empty($param['cate_id']) )
        {
            $param['cate_id'] = intval($param['cate_id']);
            if($param['cate_id']>0)
            {
                $query .= " AND cat_id={$param['cate_id']}";
            }
        }
        
        $options_query = '';
        
        if( isset( $param['options'] ) && !empty($param['options']) )
        {
            $options_query = self::parseOptions( $param['options'] );
        }

        $query = "is_on_sale = 1 {$options_query} AND (".$query.")";
        

        $order_by = "is_recommend desc,sort desc,is_new desc,is_hot desc";

        if( isset( $param['order_by'] ) && !empty($param['order_by']) )
        {

            if( array_key_exists( $param['order_by'], self::ORDER_BY_AVA ) )
            {
                
                $order_way = ( $param['order_way'] == "up" ||  $param['order_way'] == "1" ) ? " asc" :" desc";

                $order_by = self::ORDER_BY_AVA[$param['order_by']].$order_way;
            }
        }

        $page = I("p") ? I('p') : ( I('page') ? I('page') : 1 );

        $res = M(self::GOODS_TABLE)
        ->where($query)
        ->fetchSql(0)
        ->page($page,10)
        ->order($order_by)
        ->select();
// var_dump($res);die;
        foreach ($res as $key => &$v) 
        {
            $v['original_img'] = parseMediaUrl($v['original_img']);
        }

        #设置筛选条件
        $result = [
            "list" => $res,
            "options" => self::builSearchOptions($param['keyword'],$query)
        ];

        // 记录
        $param['keyword'] = $keywords;
        self::record( $param,$user_id);
        // var_dump($result);

        return $result;
    }

    /**
     * 构造商品搜索的筛选项
     * @param $keyword
     */ 
    public static function builSearchOptions($keyword,$query = '')
    {

        #计算平均价格
        $avg = M(self::GOODS_TABLE)->where($query)->Avg("shop_price");

        $avg = $avg > 100 ? intval($avg) : 100;

        $point1 = intval($avg * 0.2);
        $point2 = intval($avg * 0.5);
        $point3 = intval($avg * 0.8);
        $key_vs['shop_price'] = [
           [
                'title' => "<{$point1}",
                'value' => "< {$point1}"
           ],
           [
                'title' => "{$point1}-{$point2}",
                'value' => "BETWEEN {$point1} AND {$point2}"
           ],
           [
                'title' => "{$point2}-{$point3}",
                'value' => "BETWEEN {$point2} AND {$point3}"
           ],
           [
                'title' => ">{$point3}",
                'value' => "> {$point3}"
            ]
        ];        

        return [
           [
                "key" => "shop_price",
                "key_name" => "价格",
                "values" => $key_vs['shop_price']
            ],
        ];
    }

    /**解析option查询参数***/ 
    public static function parseOptions($options)
    {
        $str = '';
        $options = json_decode($options,1);
        if($options)
        {
            $str .= " AND";
            foreach($options as $key => $v)
            {
                if( empty($v) )
                    continue;
                
                if( 1 == count($v) )
                {
                    $str .= " ( {$key} {$v[0]} )";
                    continue;
                }
                $str .= " ( ";
                $str_im = [];
                foreach($v as &$vv)
                {
                    $str_im[] = "{$key} {$vv}";
                }
                $str .= implode(" OR ",$str_im);
                $str .= ")";
                unset($vv); 
            }   
            unset($key);
            unset($v);
        }

        return $str;
    }

    /**
     * 获取搜索的热词
     * @param $p/$page
     * @param $start_time 默认7天前 时间戳
     * @param $end_time 默认现在时间戳
     */ 
    public static function getHotWords($param=null)
    {
        $page = I("p") ? I('p') : ( I('page') ? I('page') : 1 );

        $start_time = isset($param['start_time']) ? $param['start_time'] : strtotime("-7 days");
        $end_time = isset($param['end_time']) ? $param['end_time'] : time();

        $cache_key = "SEARCH_HOT_WORD_KEY".substr($end_time,0,7);

        $cache = S($cache_key);

        if( $cache )
            return $cache;

        $where = [
            "create_time" => ["between",[$start_time,$end_time]]
        ];

        $res = M(self::SEARCH_RECORD)
            ->where($where)
            ->field(" DISTINCT keywords as word,count( * ) as num")
            ->group("word")
            ->order("num desc")
            ->fetchSql(0)
            ->page($page,10)
            ->select();

        S($cache_key,$res,300);
        return $res;
    }

    /**
     * 根据关键词检索分类信息
     * 
     * */ 
    protected static function getCates($keyword)
    {
        $hash = md5($keyword);

        $cache = S("saerch_goods_cate_".$hash); 


        if($cache)
        return $cache;

        $list = M(self::GOODS_CATE_TABLE)->where("name REGEXP '{$keyword}' OR mobile_name REGEXP '{$keyword}'")->field("id")->fetchSql(0)->select();
        // var_dump($list);die;
        if($list)
        {
            $ids = [];
            foreach($list as $k => $v)
            {
                $ids[] = $v['id'];
            }

            $list = $ids;
            unset($k);
            unset($v);
            unset($ids);

            S("saerch_goods_cate_".$hash,$list,300);
        }

        return $list;
    }


    /** 
    * 处理分词
    * @param $keyword string 输入
    * @param $removeMark boolean 是否去除标点符号
    * @return array
    */ 
    public static function swcs($keyword,$removeMark = true)
    {
        $VicWord = new VicWord('igb');

        $keywords = $VicWord->getWord($keyword);

        $res = [];

        if( $removeMark )
        {
            foreach($keywords as $k => $v)
            {
                $v = self::removeMark($v[0]);
                if( $v )
                {
                    $res[] = $v;
                }
            }
        }else{
            foreach($keywords as $k => $v)
            {
                $v = $v[0];
                if( $v )
                {
                    $res[] = $v;
                }
            }
        }

        return $res;
    }

    public static function removeMark($str)
    {
        $char = "。，、！？：；﹑•＂…‘’“”〝〞∕¦‖—　〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔！¡？¿﹖﹌﹏﹋＇´ˊˋ―﹫︳︴¯＿￣﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼（）";
 
        $pattern = array(
            "/[[:punct:]]/i", //英文标点符号
            '/['.$char.']/u', //中文标点符号
            '/[ ]{2,}/'
        );
        return preg_replace($pattern, '', $str);
    } 



    /**
     * 搜索
     * @param $keyword String 必填
     * @param $user_id int 可选默认0
     * @param $p int 可选默认1
     * @param $shop_id int 可选默认全部
     * @return mix
     */ 
    public static function record($param,$user_id = 0)
    {

        if( !is_array($param['keyword']) )
        {
            return M(self::SEARCH_RECORD)->add([
                "user_id" => $user_id,
                "keywords" => $param['keyword'],
                "type" => $param['type'],
                "extra_id" => $param['extra_id'],
                "create_time" => time()
            ]);
        }

        if( count( $param['keyword'] ) == 1 )
        {
            return M(self::SEARCH_RECORD)->add([
                "user_id" => $user_id,
                "keywords" => $param['keyword'][0],
                "type" => $param['type'],
                "extra_id" => $param['extra_id'],
                "create_time" => time()
            ]);
        }

        $data = [];

        $baseData = [
            "user_id" => $user_id,
            "keywords" => "",
            "type" => $param['type'],
            "extra_id" => $param['extra_id'],
            "create_time" => time()
        ];

        foreach($param['keyword'] as $v )
        {
            $baseData["keywords"] = $v;
            $data[] = $baseData;
        }

        return M(self::SEARCH_RECORD)->addAll($data);
    }
    
}